import time
from abc import ABC, abstractmethod
import threading
import queue
import logging
import pyaudio
from fastapi import FastAPI, WebSocket, WebSocketDisconnect

logger = logging.getLogger(__name__)


class WebSocketRecorder:
    """通过WebSocket接收前端音频，并进行后端分帧处理"""

    def __init__(self, config):
        self.running = True #运行状态
        self.audio_queue: queue.Queue = None #音频数据队列
        self._buffer = bytearray() #缓冲区
        self._frame_size_bytes = 512 * 2  #每帧音频大小1024    512采样×2字节/样本512  samples × 2 bytes/sample for 16kHz Int16 PCM

    def startRecording(self, audio_queue: queue.Queue):
        self.audio_queue = audio_queue
        self.running = True

    def putAudio(self, data: bytes):
        """接收原始 PCM 数据，将其缓冲并分帧后存入 audio_queue"""
        if not self.running:
            logger.info(f"录音已暂停，丢弃数据")
            return
        # 累积数据(字节数据累积)
        self._buffer.extend(data)

        # 按 512 样本（1024 字节）分片；每凑够1024字节就切分一帧，放入队列
        while len(self._buffer) >= self._frame_size_bytes:
            chunk = bytes(self._buffer[:self._frame_size_bytes])
            # 放入队列
            try:
                self.audio_queue.put(chunk, block=False)
            except queue.Full:
                logger.warning("audio_queue 已满，丢弃一帧音频")
            # 移除已用数据
            del self._buffer[:self._frame_size_bytes]

    def stopRecording(self):
        """停止录音，并将缓冲区剩余数据清理"""
        self.running = False
        if hasattr(self, '_buffer'):
            if self._buffer:
                logger.info(f"剩余缓冲数据未满一帧：{len(self._buffer)} 字节，将被丢弃")
            self._buffer.clear()
        logger.info("录音已停止")


def create_instance(class_name, *args, **kwargs):
    # 获取类对象
    cls = globals().get(class_name)
    if cls:
        # 创建并返回实例
        return cls(*args, **kwargs)
    else:
        raise ValueError(f"Class {class_name} not found")


if __name__ == "__main__":
    # audio_queue = queue.Queue()
    # recorderPyAudio = WebSocketRecorder(AbstractRecorder)
    # recorderPyAudio.start_recording()
    # time.sleep(10)
    # 创建一个简单的配置字典
    config = {}

    audio_queue = queue.Queue()# 音频数据队列

    # 测试 WebSocketRecorder
    ws_recorder = WebSocketRecorder(config)#实例化
    ws_recorder.startRecording(audio_queue)#将音频队列与录音器关联

    # 模拟发送一些音频数据
    test_data = bytes([i % 256 for i in range(8012)])  # 模拟4096字节的音频数据
    ws_recorder.putAudio(test_data)#数据累积+分帧处理

    time.sleep(1)  # 等待数据处理
    ws_recorder.stopRecording()
    print(f"WebSocketRecorder测试完成，队列中有 {audio_queue.qsize()} 帧音频数据")

